#include "Blockqueue.hpp"
#include "Task.hpp"
#include <pthread.h>
#include <ctime>
using namespace BlockQueueModule;
using namespace TaskModule;

void* Consumer(void* args)
{
    BlockQueue<Task>* bq = static_cast<BlockQueue<Task>*>(args);
    while(true)
    {
        Task t;
        //1.从bq拿到数据
        bq->Pop(&t);
        //2.做处理
        t.Excute();
        printf("Consumer 处理完成一个任务: %d + %d = %d\n",t.X(),t.Y(),t.Result());
    }
}
void* Productor(void* args)
{
    BlockQueue<Task>* bq = static_cast<BlockQueue<Task>*>(args);
    while(true)
    {
        //1.从外部获取数据
        int x = rand() % 10 + 1; //[1,10]
        int y = rand() % 20 + 1;
        Task t(x,y);
        // t.Excute();
        //2.生产到bq中
        bq->Equeue(t);
        printf("productor 生产了一个任务: %d + %d = ?\n",t.X(),t.Y());
    }
}
int main()
{
    srand(time(0)^getpid());
    //多生产，多消费模型
    pthread_t c1,c2,p1,p2,p3;
    //交易场所不仅仅可以用来传递数据，还可以用来传递任务
    BlockQueue<Task> *bq = new BlockQueue<Task>(5);

    pthread_create(&c1,nullptr,Consumer,bq);
    pthread_create(&c2,nullptr,Consumer,bq);
    pthread_create(&p1,nullptr,Productor,bq);
    pthread_create(&p2,nullptr,Productor,bq);
    pthread_create(&p3,nullptr,Productor,bq);

    pthread_join(c1,nullptr);
    pthread_join(c2,nullptr);
    pthread_join(p1,nullptr);
    pthread_join(p2,nullptr);
    pthread_join(p3,nullptr);
    
    delete bq;
    return 0;
}